fsck_one_object (OstreeRepo *repo,
const char *checksum,
OstreeObjectType objtype,
+ GHashTable *object_parents,
+ GVariant *key,
gboolean *out_found_corruption,
GCancellable *cancellable,
GError **error)
g_autoptr(GError) temp_error = NULL;
if (!ostree_repo_fsck_object (repo, objtype, checksum, cancellable, &temp_error))
{
+ gboolean object_missing = FALSE;
+
if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
{
g_clear_error (&temp_error);
g_printerr ("Object missing: %s.%s\n", checksum,
ostree_object_type_to_string (objtype));
- *out_found_corruption = TRUE;
+ object_missing = TRUE;
}
else
{
{
g_printerr ("%s\n", temp_error->message);
(void) ostree_repo_delete_object (repo, objtype, checksum, cancellable, NULL);
- *out_found_corruption = TRUE;
+ object_missing = TRUE;
}
else
{
return FALSE;
}
}
+
+ if (object_missing)
+ {
+ *out_found_corruption = TRUE;
+
+ if (object_parents != NULL && objtype != OSTREE_OBJECT_TYPE_COMMIT)
+ {
+ g_auto(GStrv) parent_commits = ostree_repo_traverse_parents_get_commits (object_parents, key);
+ int i;
+
+ /* The commit was missing or deleted, mark the commit partial */
+ for (i = 0; parent_commits[i] != NULL; i++)
+ {
+ const char *parent_commit = parent_commits[i];
+ g_printerr ("Marking commit %s as partial\n", parent_commit);
+ if (!ostree_repo_mark_commit_partial (repo, parent_commit, TRUE, error))
+ return FALSE;
+ }
+ }
+ }
}
return TRUE;
GError **error)
{
g_autoptr(GHashTable) reachable_objects = ostree_repo_traverse_new_reachable ();
+ g_autoptr(GHashTable) object_parents = ostree_repo_traverse_new_parents ();
GHashTableIter hash_iter;
gpointer key, value;
g_assert (objtype == OSTREE_OBJECT_TYPE_COMMIT);
- if (!ostree_repo_traverse_commit_union (repo, checksum, 0, reachable_objects,
- cancellable, error))
+ if (!ostree_repo_traverse_commit_union_with_parents (repo, checksum, 0, reachable_objects, object_parents,
+ cancellable, error))
return FALSE;
}
ostree_object_name_deserialize (serialized_key, &checksum, &objtype);
- if (!fsck_one_object (repo, checksum, objtype, out_found_corruption,
- cancellable, error))
+ if (!fsck_one_object (repo, checksum, objtype,
+ object_parents, serialized_key,
+ out_found_corruption, cancellable, error))
return FALSE;
i++;
GError **error)
{
if (!fsck_one_object (repo, checksum, OSTREE_OBJECT_TYPE_COMMIT,
- found_corruption,
+ NULL, NULL, found_corruption,
cancellable, error))
return FALSE;
ostree --repo=bare-repo remote add origin --set=gpg-verify=false $(cat ${test_tmpdir}/httpd-address)
log_timestamps ostree --repo=bare-repo pull --disable-static-deltas origin ${host_nonremoteref}
+echo "ok pull"
+
+# fsck marks commits partial
+# https://github.com/ostreedev/ostree/pull/1533
+for d in $(find bare-repo/objects/ -maxdepth 1 -type d); do
+ (find ${d} -name '*.file' || true) | head -20 | xargs rm -vf
+done
+if ostree --repo=bare-repo fsck; then
+ fatal "fsck unexpectedly succeeded"
+fi
+ostree --repo=bare-repo pull origin ${host_nonremoteref}
+# Don't need a full fsck here
+ostree --repo=bare-repo ls origin:${host_nonremoteref} >/dev/null
+
rm bare-repo repo -rf
# Try copying the host's repo across a mountpoint for direct
cd ..
umount mnt
+# Cleanup
kill -TERM $(cat ${test_tmpdir}/httpd-pid)
echo "ok"
date
set -euo pipefail
-echo "1..6"
+echo "1..8"
. $(dirname $0)/libtest.sh
fi
assert_file_has_content_literal err.txt 'Invalid / in filename ../afile'
echo "ok path traverse checkout"
+
+cd ${test_tmpdir}
+rm repo files -rf
+setup_test_repository "bare"
+
+rev=$($OSTREE rev-parse test2)
+
+filechecksum=$(ostree_file_path_to_checksum repo test2 /firstfile)
+rm repo/$(ostree_checksum_to_relative_object_path repo $filechecksum)
+
+assert_not_has_file repo/state/${rev}.commitpartial
+
+if $OSTREE fsck -q 2>err.txt; then
+ assert_not_reached "fsck unexpectedly succeeded"
+fi
+assert_file_has_content_literal err.txt "Object missing:"
+assert_file_has_content_literal err.txt "Marking commit $rev as partial"
+assert_has_file repo/state/${rev}.commitpartial
+
+echo "ok missing file"
+
+cd ${test_tmpdir}
+rm repo files -rf
+setup_test_repository "bare"
+
+rev=$($OSTREE rev-parse test2)
+
+filechecksum=$(ostree_file_path_to_checksum repo test2 /firstfile)
+echo corrupted >> repo/$(ostree_checksum_to_relative_object_path repo $filechecksum)
+
+assert_not_has_file repo/state/${rev}.commitpartial
+
+if $OSTREE fsck -q --delete 2>err.txt; then
+ assert_not_reached "fsck unexpectedly succeeded"
+fi
+assert_file_has_content_literal err.txt "Corrupted file object;"
+assert_file_has_content_literal err.txt "Marking commit $rev as partial"
+assert_has_file repo/state/${rev}.commitpartial
+
+echo "ok corrupt file"